<?php

namespace api\controller;

// +----------------------------------------------------------------------
// | 会话控制层
// +----------------------------------------------------------------------

use common\controller\VerifyController;
use common\exception\LogicException;
use common\service\ChatService;
use common\service\UserService;
use common\validate\Chat;
use support\ErrorCode;
use think\Request;

class ChatController extends VerifyController
{
    /**
     * @var \common\service\ChatService
     */
    protected $chatService;

    public function __construct()
    {
        parent::__construct();
        $this->chatService = new ChatService();
    }

    /**
     * 创建会话
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function createChat(Request $request)
    {
        try {
            $resData = $this->chatService->createChat($request->getUserId(), $request->param());
            return json(success_response('Chat created successfully', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 创建群聊(包含可传部门id)
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function createGroupChat(Request $request)
    {
        $param = $request->param();
        $data = $param['data'];
        $validator = new Chat();
        $validator->scene("CreateGroupChats");
        foreach ($data['receiver'] as $item) {
            if (!$validator->check($item)) {
                throw_strack_exception("[create_group_chat_data] " . $validator->getError(), ErrorCode::REQUEST_PARAM_ERROR);
            }
        }
        try {
            $resData = $this->chatService->createGroupChat($request->getUserId(), $request->getTenantId(), $request->param());
            if (!empty($resData)) {
                return json(success_response('Chat created successfully', $resData));
            } else {
                return json(success_response('Chat created failure', $resData));
            }
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }

    }


    /**
     * 获取用户会话列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getUserChatList(Request $request)
    {
        try {
            $param = $request->param();
            $resData = $this->chatService->getUserChatList($request->getUserId(), $request->getTenantId(), $param);
            return json(success_response('Get user chat list successfully', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取未读的会话列表
     * @param Request $request
     * @return \think\Response
     */
    public function getUserUnreadChatList(Request $request)
    {
        try {
            $resData = $this->chatService->getUserUnreadChatList($request->getUserId());
            return json(success_response('Get user unread chat list successfully', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取会话未读消息
     * @param Request $request
     * @return \think\Response
     */
    public function getUserUnreadChatMessage(Request $request)
    {
        try {
            $resData = $this->chatService->getUserUnreadChatMessage($request->getUserId(), $request->param());
            return json(success_response('Get user unread chat message successfully', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取会话基础信息
     * @param Request $request
     * @return \think\Response
     */
    public function getBaseInfo(Request $request)
    {
        try {
            $param = $request->param();
            $resData = $this->chatService->getBaseInfo($request->getUserId(), $param['param']['filter']);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 会话用户列表
     * @param Request $request
     * @return \think\Response
     */
    public function getUserList(Request $request)
    {
        try {
            $param = $request->param();
            $resData = $this->chatService->getUserList($param['param'], $request->getUserId());
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 创建租户聊天群
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function createTenantChat(Request $request)
    {
        try {
            $reData = $this->chatService->createTenantChat($request->param());
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 项目聊天会话列表
     * @param Request $request
     * @return \think\Response
     */
    public function projectChatList(Request $request)
    {
        try {
            $reData = $this->chatService->projectChatList($request->param(), $request->getUserId());
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 外部聊天会话列表
     * @param Request $request
     * @return \think\Response
     */
    public function outSideChatList(Request $request)
    {
        try {
            $reData = $this->chatService->outSideChatList($request->param(), $request->getUserId());
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function update(Request $request)
    {
        try {
            $param = $request->param();
            $oldData = $this->chatService->getChatDataById($param['data']['id']);
            if ($oldData['link_type'] != 'entity') {
                $this->chatService->checkChatNameIsAdmin($param['data'], $oldData, $request->getUserId());
            }
            $data = parent::update($request);
            $this->chatService->checkChatName($param['data'], $oldData, $request->getUserId());
            return $data;
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 删除会话
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function delete(Request $request)
    {
        try {
            $param = $request->param();
            $reData = $this->chatService->delete($param['param']);
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 解除会话
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function disbandChat(Request $request)
    {
        try {
            $param = $request->param();
            $reData = $this->chatService->disbandChat($param['param'], $request->getUserId());
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取总的未读消息数
     * @param Request $request
     * @return \think\Response
     */
    public function getUnreadMessageCount(Request $request)
    {
        try {
            $reData = $this->chatService->getUnreadMessageCount($request->getUserId(), $request->getTenantId());
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 刷新会话的最后一次消息时间
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function writeChatEditedAt(Request $request)
    {
        try {
            $resData = $this->chatService->writeChatEditedAt($request->param()['param']);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 查找当前用户单个聊天
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function findUserChat(Request $request)
    {
        try {
            $param = $request->param()['param'];
            $findMethod = $param['find_method'] ?? 'base_filter';
            $resData = $this->chatService->findUserChat($param['filter'] ?? [], $findMethod, $request->getUserId());
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 批量创建会话
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function batchCreateChat(Request $request)
    {
        try {
            $param = $request->param();
            $resData = $this->chatService->batchCreateChat($param);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 批量解除会话
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function bathDisbandChat(Request $request)
    {
        try {
            $param = $request->param();
            $reData = $this->chatService->bathDisbandChat($param['param']);
            return json(success_response('', $reData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取会话是否存在未读消息
     * @param Request $request
     * @return \think\Response
     */
    public function getChatIsUnread(Request $request)
    {
        try {
            $param = $request->param()['param'];
            $filter = $param['filter'];
            $userId = $filter['user_id'] ?? $request->getUserId();
            unset($filter['user_id']);
            $resData = $this->chatService->getChatIsUnread($filter, $userId);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 更新群头像
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function updateAvatar(Request $request)
    {
        try {
            $param = $request->param();
            $resData = $this->chatService->updateChatAvatar($param['data'], $request->getUserId());
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 查询制片小助手的未读消息统计
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getProducerAssistantMessageUnReadCount(Request $request)
    {
        $param = $request->param()['param'] ?? [];
        try {
            $resData = $this->chatService->getProducerAssistantMessageUnReadCount($request->getUserId(), $param);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获得一个一对一的会话
     * @param Request $request
     * @return \think\Response|void
     * @throws \Exception
     */
    public function getOneToOneChat(Request $request)
    {
        $param = $request->param()['param'];
        $receiver = $param['receiver'];
        $sender = $param['sender'];
        try {
            $resData = $this->chatService->getOneToOneChat($receiver, $sender);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获得一个系统一对一的会话
     * @param Request $request
     * @return \think\Response|void
     * @throws \Exception
     */
    public function getOneToSystemChat(Request $request)
    {
        $param = $request->param()['param'];
        $receiver = $param['receiver'];
        $notifyUserMark = $param['system_user_mark'];
        $noticeUser = UserService::getInstance()->getSystemNoticeUser($notifyUserMark);
        try {
            $resData = $this->chatService->getOneToOneChat($receiver, $noticeUser['id'], ['link_type' => $notifyUserMark, 'edited_at' => time()]);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 会话是否存在消息
     * @param Request $request
     * @return \think\Response|void
     */
    public function hasMessage(Request $request)
    {
        $filter = $request->param()['param']['filter'];
        try {
            $resData = $this->chatService->hasMessage($filter);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }
}
